package com.zilue.payment.gateway.manage;

import com.alibaba.fastjson.JSON;
import com.zilue.balance.domain.BaseOrderInfo;
import com.zilue.balance.returnresult.Result;
import com.zilue.payment.gateway.domain.CorpDO;
import com.zilue.payment.gateway.domain.PayOrderDO;
import com.zilue.payment.gateway.exception.BizManagerException;
import com.zilue.payment.gateway.method.remote.BalancePayRemote;
import com.zilue.payment.gateway.paramter.order.PayParameter;
import com.zilue.payment.gateway.reurndata.PublicReturn;
import com.zilue.payment.gateway.reurndata.enums.BusinessStatusEnum;
import com.zilue.payment.gateway.reurndata.enums.RequestStatusEnum;
import com.zilue.payment.gateway.reurndata.order.PayReturn;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by zilue on 2017/3/9.
 */
@Service
public class OrderPayManager extends BaseManager {
    private static final Logger logger = Logger.getLogger(OrderPayManager.class);

    @Autowired
    private BalancePayRemote balancePayRemote;

    public PublicReturn pay(CorpDO corpDO, PayParameter payParameter){
        PublicReturn payReturn = new PublicReturn(RequestStatusEnum.RequestSuccess);
        //1.查询订单号
        PayOrderDO payOrderDO = queryByOrderNoOutTradeNo(payParameter.getOrder_no(), payParameter.getOut_trade_no(), null, corpDO.getParentCorpId(), corpDO.getCorpId());
        if (payOrderDO == null) {
            payReturn.setBusinessStatus(BusinessStatusEnum.OrderNotExist);
            return payReturn;
        }
        if (PayOrderDO.STATUS_WAIT_FOR_PAY.equals(payOrderDO.getStatus())) {
            //2.检查支付认证码
            if (!payAuthCodeCheck(corpDO.getAppid(), payParameter.getAuth_code())) {
                payReturn.setBusinessStatus(BusinessStatusEnum.PayAuthCodeIllegal);
                return payReturn;
            }
            //3.支付并返回结果
            return pay(payOrderDO, payParameter);
        } else if (PayOrderDO.STATUS_CANCLE.equals(payOrderDO.getStatus())) {
            payReturn.setBusinessStatus(BusinessStatusEnum.OrderCancled);
            return payReturn;
        } else if (PayOrderDO.STATUS_CLOSED.equals(payOrderDO.getStatus())) {
            payReturn.setBusinessStatus(BusinessStatusEnum.OrderClosed);
            return payReturn;
        } else if (PayOrderDO.STATUS_SUCCESS.equals(payOrderDO.getStatus())) {
            payReturn.setBusinessStatus(BusinessStatusEnum.OrderSucceed);
            return payReturn;
        } else if (PayOrderDO.STATUS_REFUND.equals(payOrderDO.getStatus())) {
            payReturn.setBusinessStatus(BusinessStatusEnum.OrderRefunded);
            return payReturn;
        } else {
            payReturn.setBusinessStatus(BusinessStatusEnum.Busyness);
            return payReturn;
        }
    }

    @Transactional
    public PayReturn pay(PayOrderDO payOrder, PayParameter payParameter) {
        boolean updateOK = updatePayOrderStatus(payOrder.getId(), PayOrderDO.STATUS_WAIT_FOR_PAY, PayOrderDO.STATUS_SUCCESS);
        if (!updateOK) {
            throw new BizManagerException(BusinessStatusEnum.Busyness);
        }
        Result<BaseOrderInfo> payResult = balancePayRemote.pay(payOrder.getAccountId(), payOrder.getSubCorpId(), payOrder.getTotalAmount(), payOrder.getOutTradeNo(), 1, payOrder.getTerminalId(), payOrder.getOperatorId());
        logger.info(" 支付订单：" + payOrder + " 支付结果：" + payResult);
        if (!payResult.isSuccess()) {
            throw new BizManagerException(BusinessStatusEnum.OrderPayFailed, payResult.getMsg());
        }
        Date payDate = new Date();
        boolean updatePayDate = updatePayOrderPayDate(payOrder.getId(), payDate);
        if (!updatePayDate) {
            logger.error("更新账单支付时间异常  " + JSON.toJSONString(payOrder));
        }
        String outPayNo = payResult.getData().getLogNo();
        boolean ok = addPayOrderOutPayNo(payOrder.getId(), outPayNo);
        if (!ok) {
            logger.error("更新账单第三方流水号异常：  " + JSON.toJSONString(payOrder) + " 流水号：" + outPayNo);
        }
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        PayReturn payReturn = new PayReturn(RequestStatusEnum.RequestSuccess);
        payReturn.setOrder_no(payOrder.getOrderNo());
        payReturn.setOut_trade_no(payOrder.getOutTradeNo());
        payReturn.setOut_pay_no(outPayNo);
        payReturn.setTotal_amount(payOrder.getTotalAmount());
        payReturn.setBuyer_id(getMaskString(payOrder.getAccountId()));
        payReturn.setPayment_time(dateFormat.format(payDate));
        payReturn.setBusinessStatus(BusinessStatusEnum.OrderPaySuccess);
        return payReturn;
    }

    private String getMaskString(String target) {
        if (StringUtils.isEmpty(target)) {
            return target;
        }
        int len = target.length();
        int maskLen = target.length() / 2;
        String mask = "";
        for (int i = 0; i < maskLen; i++) {
            mask += "*";
        }
        String maskString = target.substring(0, len / 4 - 1) + mask + target.substring((len / 4) * 3, len);
        return maskString;
    }


    public boolean payAuthCodeCheck(String appid, String authCode) {
        if (StringUtils.isEmpty(authCode))
            return false;

        CorpDO corpDO = queryCorpByAppid(appid);
        if (StringUtils.equals(authCode, corpDO.getNonConfidentialPayCode())) {//免密和支付
            return true;
        }
        //获取用户支付授权码 TODO ，可以用短信的方式从redis中取，或者固定密码（后期才做）
        return false;
    }

}
